#pragma once
#include <iostream>
#include <memory>
#include <dirent.h>
#include <sys/stat.h>
#include "face_feature_arcface_api.h"
#include "arcface_feature_gpu_api.h"
#include <algorithm>
#include <chrono>
using namespace arcfacefeature;
using namespace arcfacefeaturegpu;

int64_t CurrentTimeMillis()
{
    int64_t timems = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
    return timems;
}
void FindFiles(const std::string &path, std::vector<std::string> &files)
{
    struct stat rst;
    if (stat(const_cast<char *>(path.c_str()), &rst) != 0)
        return;
    DIR *dirpt = opendir(path.data());
    dirent *entry;
    while (entry = readdir(dirpt))
    {
        /* code */
        if (entry->d_type == DT_REG)
            files.emplace_back(entry->d_name);
    }
    closedir(dirpt);
}

void PrintVector(const std::vector<float> vec)
{

    for (auto iter = vec.cbegin(); iter != vec.cend(); iter++)
    {
        std::cout << (*iter) << " ";
    }
}

void face_feature_gpu()
{

    std::shared_ptr<ArcfaceFeatureGpuApi> feature_gpu = std::make_shared<ArcfaceFeatureGpuApi>(0,
                                                                                               "/home/user/yyz_workspace_disk/Code/algolib/input_models/onnx_model/insightface_arcface_res18/backbone_arcface.onnx",
                                                                                               "/home/user/yyz_workspace_disk/Code/algolib/input_models/trt_model/");

    std::string file_path = "/home/user/yyz_workspace_disk/Code/face/insightface/test_img/test0.png";

    cv::Mat img1 = cv::imread(file_path);
    std::vector<float> feature1;

    feature_gpu->Execute(img1, feature1);
    PrintVector(feature1);
}

void face_feature_gpu_batch()
{

    std::vector<cv::Mat> mat_vec;

    std::shared_ptr<ArcfaceFeatureGpuApi> feature_gpu = std::make_shared<ArcfaceFeatureGpuApi>(0,
                                                                                               "/home/user/yyz_workspace_disk/Code/algolib/input_models/onnx_model/insightface_arcface_res18/backbone_dynamic_axes.onnx",
                                                                                               "/home/user/yyz_workspace_disk/Code/algolib/input_models/trt_model/",
                                                                                               8);

    std::string file_path = "/home/user/yyz_workspace_disk/Code/face/insightface/test_img/test0.png";

    cv::Mat img1 = cv::imread(file_path);
    mat_vec.push_back(img1);
    // std::vector<float> feature1;

    // feature_gpu->Execute(img1, feature1);
    // PrintVector(feature1);

    // // PrintVector(feature1);
    // std::cout << "#############################################" << std::endl;

    std::string file_path1 = "/home/user/yyz_workspace_disk/Code/face/insightface/test_img/test1.jpg";

    cv::Mat img2 = cv::imread(file_path1);
    mat_vec.push_back(img2);

    auto features = feature_gpu->Execute(mat_vec);

    PrintVector(features[0]);

    std::cout << "#############################################" << std::endl;

    PrintVector(features[1]);

    // std::vector<float> feature2;
    // feature_gpu->Execute(img2, feature2);
    // PrintVector(feature2);
}

void test_arcfacefeature()
{
    std::shared_ptr<ArcfaceFeature_api> feature = std::make_shared<ArcfaceFeature_api>(0,
                                                                                       "/home/user/yyz_workspace_disk/Code/algolib/input_models/onnx_model/retinaface_mobilenet/backbone_arcface.onnx",
                                                                                       "/home/user/yyz_workspace_disk/Code/algolib/input_models/trt_model/");

    std::cout << "test" << std::endl;
    // cv::Mat img = cv::Mat::zeros(270, 480, CV_8UC3);

    // std::string root="/home/klyr/4T/seg/data/testresult/imgs1/";
    std::string root = "/home/user/yyz_workspace_disk/Code/insightface/test_img/test/";
    std::vector<std::string> files;
    FindFiles(root, files);

    for (int i = 0; i < files.size(); i++)
    {
        std::cout << files[i] << std::endl;
        std::string file_path = root + files[i]; // "/home/administrator/imgs/[4]14_21_33.jpg";   // ## '/home/xixi/1.jpg'
        cv::Mat img = cv::imread(file_path);
        if (img.empty())
        {
            std::cout << "img is empty()" << std::endl;
            continue;
        }
        auto result = feature->Execute(img);
        PrintVector(result);
    }
}
